﻿package no.doomsday.aronning.engines.verlets.constraints 
{
	import flash.display.Graphics;
	import flash.geom.Rectangle;
	import no.doomsday.aronning.utilities.parameters.Parameter;
	import no.doomsday.aronning.engines.verlets.IRenderable;
	import no.doomsday.aronning.engines.verlets.IUpdatable;
	import no.doomsday.aronning.engines.verlets.utils.LinkedListNode;
	import no.doomsday.aronning.engines.verlets.Verlet;
	import no.doomsday.aronning.engines.verlets.VerletSystem;
	
	/**
	 * ...
	 * @author Andreas Rønning
	 */
	public class RectangleConstraint extends AbstractConstraint implements IRenderable, IUpdatable
	{
		public var x:Number;
		public var y:Number;
		public var width:Number;
		public var height:Number;
		public var associatedSystem:VerletSystem;
		public var constrainAll:Boolean;
		public var friction:Parameter;
		public function RectangleConstraint(dim:Rectangle, associatedSystem:VerletSystem, constrainAll:Boolean, friction:Parameter )
		{
			this.friction = friction;
			this.associatedSystem = associatedSystem;
			this.constrainAll = constrainAll;
			this.x = dim.x;
			this.y = dim.y;
			this.width = dim.width;
			this.height = dim.height;
		}
			
		public function update(timeStep:Number = 0):void
		{
			var v:Verlet;
			var n:LinkedListNode;
			var diff:Number;
			if (constrainAll) {
				n = associatedSystem.startVerlet;
				while (n.next) {
					n = n.next;
					v = n as Verlet;
					if (v.x > x + width || v.x < x) {
						//tangential friction only
						v.x = Math.min(x + width, Math.max(x, v.x));	
						diff = v.y - v.oldY;
						v.oldY += diff * friction.value;
						
					}
					if (v.y > y + height || v.y < y) {
						//tangential friction only
						v.y = Math.min(y + height, Math.max(y, v.y));
						diff = v.x - v.oldX;
						v.oldX += diff * friction.value;
					}
				}
			}else{
				for (var i:int = constrainedVerlets.length; i--; ) 
				{
					v = constrainedVerlets[i];
					v.x = Math.min(x+width, Math.max(x, v.x));
					v.y = Math.min(y+height, Math.max(y, v.y));
				}
			}
		}
		
		public function render(g:Graphics):void
		{
			g.lineStyle(0, 0x00FF00);
			g.drawRect(x, y, width, height);
		}		
		
	}
	
}